﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using BeanboxSoftware.BeanProxy.Internals;

namespace BeanboxSoftware.BeanProxy
{
  //3.5 doesn't have 5 param funcs/actions
  /// <summary>
  /// Extends System.Func to include a 5 parameter type
  /// </summary>
  /// <typeparam name="T1">type 1</typeparam>
  /// <typeparam name="T2">type 2</typeparam>
  /// <typeparam name="T3">type 3</typeparam>
  /// <typeparam name="T4">type 4</typeparam>
  /// <typeparam name="T5">type 5</typeparam>
  /// <typeparam name="TResult">return type</typeparam>
  /// <param name="p1">parameter 1</param>
  /// <param name="p2">parameter 2</param>
  /// <param name="p3">parameter 3</param>
  /// <param name="p4">parameter 4</param>
  /// <param name="p5">parameter 5</param>
  /// <returns></returns>
  public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 p1, T2 p2, T3 p3, T4 p4, T5 p5);

  /// <summary>
  /// Holds configuration for a Func&lt;TResult&gt;
  /// </summary>
  public class FuncConfig<TResult> : MethodConfig<Func<TResult>>
  {
    public FuncConfig(MethodConfig access) : base(access) { }
    /// <summary>
    /// A set only property that clears any current callbacks and creates a callback that returns the value given
    /// </summary>
    public TResult Return { set { ClearCallbacks(); Add(() => { return value; }); } }
  }
  /// <summary>
  /// Holds configuration for a Func&lt;T1, TResult&gt;
  /// </summary>
  public class FuncConfig<T1, TResult> : MethodConfig<Func<T1, TResult>, T1>
  {
    public FuncConfig(MethodConfig access) : base(access) { }
    /// <summary>
    /// A set only property that clears any current callbacks and creates a callback that returns the value given
    /// </summary>
    public TResult Return { set { ClearCallbacks(); Add((p1) => { return value; }); } }
  }
  /// <summary>
  /// Holds configuration for a Func&lt;T1, T2, TResult&gt;
  /// </summary>
  public class FuncConfig<T1, T2, TResult> : MethodConfig<Func<T1, T2, TResult>, T1, T2>
  {
    public FuncConfig(MethodConfig access) : base(access) { }
    /// <summary>
    /// A set only property that clears any current callbacks and creates a callback that returns the value given
    /// </summary>
    public TResult Return { set { ClearCallbacks(); Add((p1, p2) => { return value; }); } }
  }
  /// <summary>
  /// Holds configuration for a Func&lt;T1, T2, T3, TResult&gt;
  /// </summary>
  public class FuncConfig<T1, T2, T3, TResult> : MethodConfig<Func<T1, T2, T3, TResult>, T1, T2, T3>
  {
    public FuncConfig(MethodConfig access) : base(access) { }
    /// <summary>
    /// A set only property that clears any current callbacks and creates a callback that returns the value given
    /// </summary>
    public TResult Return { set { ClearCallbacks(); Add((p1, p2, p3) => { return value; }); } }
  }
  /// <summary>
  /// Holds configuration for a Func&lt;T1, T2, T3, T4, TResult&gt;
  /// </summary>
  public class FuncConfig<T1, T2, T3, T4, TResult> : MethodConfig<Func<T1, T2, T3, T4, TResult>, T1, T2, T3, T4>
  {
    public FuncConfig(MethodConfig access) : base(access) { }
    /// <summary>
    /// A set only property that clears any current callbacks and creates a callback that returns the value given
    /// </summary>
    public TResult Return { set { ClearCallbacks(); Add((p1, p2, p3, p4) => { return value; }); } }
  }
  /// <summary>
  /// Holds configuration for a Func&lt;T1, T2, T3, T4, T5, TResult&gt;
  /// </summary>
  public class FuncConfig<T1, T2, T3, T4, T5, TResult> : MethodConfig<Func<T1, T2, T3, T4, T5, TResult>, T1, T2, T3, T4, T5>
  {
    public FuncConfig(MethodConfig access) : base(access) { }
    /// <summary>
    /// A set only property that clears any current callbacks and creates a callback that returns the value given
    /// </summary>
    public TResult Return { set { ClearCallbacks(); Add((p1, p2, p3, p4, p5) => { return value; }); } }
  }
}
